import { Injectable, Compiler, Component, ComponentFactory, NgModule, Injector } from '@angular/core';

import {
    Content2ServiceProxy,
    CreateOrUpdateInput, GetContentForEditInput, SetStatusWithMenuIdInput,PreviewTokenInput, ContentConfig, PreviewServiceProxy
} from '@shared/service-proxies/service-proxies';
import { finalize } from 'rxjs/operators';
import { AppConsts } from '@shared/AppConsts';
import { IContent2DetailComponent } from './IContent2DetailComponent';
import { MessageService } from 'abp-ng2-module';
import { AppLocalizationService } from '@app/shared/common/localization/app-localization.service';
import { Content2DetailModalComponent } from './detail/content2-detail-modal.component';
import { AppSharedModule } from "@app/shared/app-shared.module";
import { MainSharedModule } from "@app/main/shared/main-shared.module";
import { AppNotifyService } from '@shared/utils/service/app-notify.service';
import { ContentFormService } from '../content/content-form.Service';
import { FileUploadHelper } from '@shared/helpers/FileUploadHelper';

@Injectable()
export class AppContent2DetailService {

    static configCache:{[key:string]:ContentConfig} = {};

    constructor(
        private _contentFormService: ContentFormService,
        private _contentServiceProxy: Content2ServiceProxy,
        private _previewServiceProxy: PreviewServiceProxy,
        private message: MessageService,
        private notify: AppNotifyService,
        private compiler: Compiler,
        private _appLocalizationService: AppLocalizationService) {

    }

    initDetailPage(vm: IContent2DetailComponent, vcInjector: Injector, isModal: boolean, callback: { (): void }) {

        if (isModal) {
            // 先打开弹窗
            if (callback) {
                callback();
            }
        } 

        let input = new GetContentForEditInput({
            menuId: vm.kind,
            customKey: vm.customKey,
            relateId: vm.relateId,
            id: vm.id
        });
        vm.isLoading = true;
        this._contentServiceProxy.getContentForEdit(input)
            .pipe(finalize(() => vm.isLoading = false))
            .subscribe(result => {
                vm.canSave =  result.managementType === 0;
                let pageConfig = vm.pageConfig;

                if (result.id) {
                    vm.randomId = result.id;
                    vm.isTemporary = false;

                    if(vm.pageConfig.prohibitAdding && result.key !== vm.customKey){
                        if(!AppContent2DetailService.configCache[result.key]){
                            this._contentServiceProxy.getConfig(vm.kind, result.key)
                            .subscribe(configResult=>{
                                AppContent2DetailService.configCache[result.key] = configResult;
                                pageConfig = configResult;
                                this._contentFormService.afterLoadData(pageConfig.detail, result);
                                vm.data = result;
                                this.initDetailPageTemplate(pageConfig, vm, vcInjector);
                            });
                        }else{
                            pageConfig = AppContent2DetailService.configCache[result.key];
                            this._contentFormService.afterLoadData(pageConfig.detail, result);
                            vm.data = result;
                            this.initDetailPageTemplate(pageConfig, vm, vcInjector);
                        }
                    }else{
                        this._contentFormService.afterLoadData(pageConfig.detail, result);
                        vm.data = result;
                        this.initDetailPageTemplate(pageConfig, vm, vcInjector);
                    }
                }else{
                    this._contentFormService.afterLoadData(pageConfig.detail, result);
                    vm.data = result;
                    vm.randomId = FileUploadHelper.newGuid();
                    vm.isTemporary = true;
                    this.initDetailPageTemplate(pageConfig, vm, vcInjector);
                }

                //this._contentFormService.initCtrls(vm);
            });
    }

    private initDetailPageTemplate(pageConfig: ContentConfig, vm: IContent2DetailComponent, vcInjector: Injector) {
        let html = this._contentFormService.getDetailPageTemplate(pageConfig);

        let permissionDic = JSON.parse(JSON.stringify(vm.permissionDic));
        if(!vm.canSave){
            for (let property in permissionDic) {
                permissionDic[property]  = false;
            }
        }

        //console.info(html);
        if (vm.cmpRef) {
            vm.cmpRef.destroy();
        }

        let tempFunc = function () {
            this.data = vm.data;
            this.permissionDic = permissionDic;
            this.randomId = vm.randomId;
            this.isTemporary = vm.isTemporary;
            this.kind = vm.kind;
            this.customKey = vm.customKey;
            this.relateId = vm.relateId;
            this.id = vm.id;
            this.dataSynchronous = vm.dataSynchronous;
        };

        this._contentFormService._diyFormService.createFormComponentFactory(this.compiler, html, tempFunc).then(factory => {
            const injector = Injector.create({ providers: [], parent: vcInjector });
            const cmpRef = vm.vc.createComponent(factory, 0, injector, []);

            cmpRef.instance.name = "dynamic-content2-component";

            vm.cmpRef = cmpRef;
        });
    }

    //-- action

    //保存并预览
    previewItem(vm: IContent2DetailComponent) {
        if (!vm.saving && !vm.isLoading) {

            if ((vm.permissionDic['Pages_Manage_Content_Create'] && !vm.id) || vm.permissionDic['Pages_Manage_Content_Update'] && vm.id) {
                vm.saving = true;
                var input = this.getFormDataToSave(vm);

                this._contentServiceProxy.createOrUpdate(input)
                    .pipe(finalize(() => vm.saving = false))
                    .subscribe((result) => {
                        this.notify.success(this._appLocalizationService.l('SavedSuccessfully'));
                        if(vm.id !== result){
                            vm.id = result;
                            if(vm.isModal){
                                this.initDetailPage(vm, vm.vc.injector, true, null);
                            }else{
                                this.initDetailPage(vm, vm.vc.injector, false, null);
                            }
                        }
                        var tokenInput=new PreviewTokenInput({menuId:vm.data.menuId,auxId:vm.data.auxId,id:result,key:vm.data.key});
                        this._previewServiceProxy.getPreviewToken(tokenInput)
                            .subscribe((tokenResult) => {
                                this.notify.success(this._appLocalizationService.l('SavedSuccessfully'));
                                window.open(AppConsts.remoteServiceBaseUrl + "/Preview/Index?token=" + tokenResult.token);
                            });
                    });
            }

        } 
    }

    // 保存
    saveItem(vm: IContent2DetailComponent) {
        if (!vm.saving && !vm.isLoading) {
            vm.saving = true;
            var input = this.getFormDataToSave(vm);

            this._contentServiceProxy.createOrUpdate(input)
                .pipe(finalize(() => vm.saving = false))
                .subscribe((result) => {
                    this.notify.success(this._appLocalizationService.l('SavedSuccessfully'));
                    this.goBack(vm, true);
                });
        }
    }

    private getFormDataToSave(vm: IContent2DetailComponent): CreateOrUpdateInput {

        let input = { "menuId": vm.kind, "customKey": vm.customKey, "relateId": vm.relateId, "randomId": vm.randomId };
        if (vm.id) {
            input['id'] = vm.id;
        } else {
            input['id'] = null;
        }

        let field: { [key: string]: any } = {};
        for (let key in vm.data) {
            field[key] = vm.data[key];
        }
        // 数据处理：html编码，时间等格式化
        this._contentFormService.beforeSubmit(vm.pageConfig.detail, field);
        input['values'] = field;

        let result = new CreateOrUpdateInput();
        result.init(input);
        return result;
    }


    deleteSingle(vm: IContent2DetailComponent) {
        if (vm.id) {
            this.message.confirm(this._appLocalizationService.l('DeleteWarningMessage'), this._appLocalizationService.l('AreYouSure'),
                (isConfirmed) => {
                    if (!isConfirmed) return;
                    this._contentServiceProxy.deleteListAysnc(vm.kind, vm.relateId, [vm.id])
                        .subscribe(() => {
                            if (vm.isModal) {
                                this.goBack(vm, true);
                            } else {
                                vm.goToNewPage();
                            }

                            this.notify.success(this._appLocalizationService.l('SuccessfullyDeleted'));
                        });
                })
        }
    }

    changeState(vm: IContent2DetailComponent, state: boolean) {
        if (vm.id) {
            let msg: string;
            if (state) {
                msg = this._appLocalizationService.l('ReleaseWarningMessage');
            }
            else {
                msg = this._appLocalizationService.l('UndoReleaseWarningMessage');
            }
            this.message.confirm(msg, this._appLocalizationService.l('AreYouSure'),
                (isConfirmed) => {
                    if (!isConfirmed) return;

                    let input = new SetStatusWithMenuIdInput();
                    input.menuId = vm.kind;
                    input.idList = [vm.id];
                    input.isActive = state;

                    this._contentServiceProxy.setStatus(input)
                        .subscribe(() => {
                            this.goBack(vm, true);
                            if (state) {
                                this.notify.success(this._appLocalizationService.l('ReleaseSuccessfully'));
                            } else {
                                this.notify.success(this._appLocalizationService.l('CancelReleaseSuccessfully'));
                            }
                        });
                })
        }
    }


    synchorizationById(vm: IContent2DetailComponent) {
        // 手动同步数据
    }

    private goBack(vm: IContent2DetailComponent, refresh: boolean) {
        if (vm.isModal) {
            let vm2 = (vm as Content2DetailModalComponent);
            if (refresh) {
                vm2.backListEvent.emit();
            }
            vm2.close();
        }
    }
}
